package com.xnew.utils;

import com.xnew.constant.Constant;

import java.text.ParseException;
import java.util.Date;
import java.util.UUID;

/**
 * 用于生产各种各样的ID
 */
public class IdUtils {

	private static String middle = "";

	static {
		middle = MathUtils.makeUpNewData(Math.abs(NetworkUtils.getHostIP().hashCode()) + "", 4) + // 4位IP地址hash
				MathUtils.makeUpNewData(NetworkUtils.getPid(), 4); // 4位PID进程hash
	}

	/**
	 * 以毫微秒做基础计数, 返回唯一有序增长ID
	 *
	 * <pre>
	 * System.nanoTime()
	 * </pre>
	 *
	 * <pre>
	 *  线程数量:   100
	 *  执行次数:   1000
	 *  平均耗时:   222 ms
	 *  数组长度:   100000
	 *  Map Size:   100000
	 * </pre>
	 *
	 * @return ID长度20位
	 */
	public static String getIncreaseIdByNanoTime() {
		return System.nanoTime() + // 时间戳-15位
				MathUtils.randomDigitNumber(5); // 随机5位数
	}

	/**
	 * 以毫秒做基础计数, 返回唯一有序增长ID, 有几率出现线程并发
	 * 
	 * <pre>
	 * System.currentTimeMillis()
	 * </pre>
	 * 
	 * <pre>
	 *  线程数量:   100
	 *  执行次数:   1000
	 *  平均耗时:   206 ms
	 *  数组长度:   100000
	 *  Map Size:   99992
	 * </pre>
	 * 
	 * @return ID长度32位
	 */
	public static String getIncreaseIdByCurrentTimeMillis() {
		return System.currentTimeMillis() + // 时间戳-14位
				middle + // 标志-8位
				MathUtils.makeUpNewData(Thread.currentThread().hashCode() + "", 3) + // 3位线程标志
				MathUtils.randomDigitNumber(7); // 随机7位数
	}

	/**
	 * 基于UUID+MD5产生唯一无序ID
	 * 
	 * <pre>
	 *  线程数量:   100
	 *  执行次数:   1000
	 *  平均耗时:       591 ms
	 *  数组长度:   100000
	 *  Map Size:   100000
	 * </pre>
	 * 
	 * @return ID长度32位
	 */
	public static String getRandomIdByUUID() {
		return DigestUtils.md5Hex(UUID.randomUUID().toString());
	}

	public static void main(String[] args) throws ParseException {
		System.out.println(String.format("%04d",Integer.parseInt("123") + 1));
	}

	synchronized public static String buildBisinessCode(String prefix) throws ParseException {
		String dateStr = DateUtils.dateFormat(new Date(), DateUtils.DATE_PATTERN);
		String bigNum = RedisUtil.get(RedisUtil.buildKey(":", new String[]{Constant.BUSINESS_CODE, prefix, dateStr}));
		if(null == bigNum || "".equals(bigNum)){
			bigNum = "0";
		}
		String thisNum = prefix + dateStr + String.format("%04d",Integer.parseInt(bigNum) + 1);
		RedisUtil.set(RedisUtil.buildKey(":", new String[]{Constant.BUSINESS_CODE, prefix, dateStr}), Integer.parseInt(bigNum) + 1);
		return thisNum;
	}

	public static String buildSerialNo(String orgNo) throws ParseException {
		String dateStr = DateUtils.dateFormat(new Date(), "yyyyMMdd");
		String bigNum = RedisUtil.get(RedisUtil.buildKey(":", new String[]{Constant.ESB_REQUEST, dateStr}));
		if(null == bigNum || "".equals(bigNum)){
			bigNum = "0";
		}
		String thisNum = String.format("%08d",Integer.parseInt(bigNum) + 1);
		RedisUtil.set(RedisUtil.buildKey(":", new String[]{Constant.ESB_REQUEST, dateStr}), Integer.parseInt(bigNum) + 1);
		return dateStr + "000000" + "00" + orgNo + thisNum;
	}

//	//生成id
//	public static Integer generateId(){
//		long id = SnowflakeIdWorker.generateId();//得到id 很长且高位很长部分是一样的数
//		StringBuilder sb=new StringBuilder(id+"");
//		StringBuilder reverse = sb.reverse();//将id翻转：我们发现id很长，且高位很长部分是一样的数
//		id=new Long(reverse.toString())/1000;//切去部分长度
//		while(id>1999999999){//1999999999以内的10位或9位或8位id;....
//			id/=10;
//		}
//		Integer _id_ = Integer.parseInt(id+"");
//		return _id_;
//	}
}
